package org.jpropeller.problem.impl;

import java.awt.Component;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.AbstractCellEditor;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.TableCellEditor;

import org.jpropeller.problem.Problem;

/**
 * A TableCellEditor for Problems.
 * For IgnorableProblems, it enables the user to choose whether or not to ignore the problem.
 */
public class ProblemCellEditor extends AbstractCellEditor implements TableCellEditor, ItemListener, ChangeListener
{
	private ProblemCellRenderer renderer;
	private Problem problem;
	
	public ProblemCellEditor()
	{
		this.renderer=new ProblemCellRenderer();
		this.renderer.getCheckBox().addItemListener(this);
		this.renderer.getSpinner().addChangeListener(this);
	}


	@Override
	public Object getCellEditorValue() {
		return renderer.getValue();
		//return renderer.getCheckBox().isSelected();
	}

	@Override
	public Component getTableCellEditorComponent(JTable table, Object value,
			boolean isSelected, int row, int column) {
		if(value instanceof Problem)
		{
			this.problem=(Problem)value;
			return renderer.getTableCellRendererComponent(table, value,
				true, true, row,column);
		}
		return new JLabel("ProblemCellEditor : object is not a Problem");
	}

	@Override
	public void itemStateChanged(ItemEvent e) {
		fireEditingStopped();
	}


	@Override
	public void stateChanged(ChangeEvent arg0) {
		if( ((NumberProblem)problem).checkNumber((Number)renderer.getSpinner().getValue()) )
		{
			fireEditingStopped();
		}
		else //undo change
		{
			Number number=((NumberProblem)problem).number().get();
			Number numberMin=((NumberProblem)problem).numberMin().get();
			Number numberMax=((NumberProblem)problem).numberMax().get();
			if(number instanceof Integer)
			{
				renderer.getSpinner().setModel(new SpinnerNumberModel(((Integer)number).intValue(),((Integer)numberMin).intValue(),((Integer)numberMax).intValue(),1));
				renderer.getSpinner().setValue(((Integer)number).intValue());
			}
			else if(number instanceof Double)
			{
				renderer.getSpinner().setModel(new SpinnerNumberModel(((Double)number).doubleValue(),((Double)numberMin).doubleValue(),((Double)numberMax).doubleValue(),0.1));
				renderer.getSpinner().setValue(((Double)number).doubleValue());
			}
			else
			{
				renderer.getSpinner().setValue(((NumberProblem)problem).number().get());
			}
		}
	}
	
}
